{{!
  Copyright (c) HashiCorp, Inc.
  SPDX-License-Identifier: BUSL-1.1
~}}

<Breadcrumb @crumb={{hash label="Topology" args=(array "topology")}} />
{{page-title "Cluster Topology"}}
<PageLayout>
  <section class="section is-full-width">
    {{#if this.isForbidden}}
      <ForbiddenMessage />
    {{else}}
      {{#if this.pre09Nodes}}
        <div class="notification is-warning">
          <div data-test-filtered-nodes-warning class="columns">
            <div class="column">
              <h3 data-test-title class="title is-4">
                Some Clients Were Filtered
              </h3>
              <p data-test-message>
                {{this.pre09Nodes.length}}
                {{if (eq this.pre09Nodes.length 1) "client was" "clients were"}}
                filtered from the topology visualization. This is most likely due to the
                {{pluralize "client" this.pre09Nodes.length}}
                running a version of Nomad
              </p>
            </div>
            <div class="column is-centered is-minimum">
              <button
                data-test-dismiss
                class="button is-warning"
                onclick={{action (mut this.pre09Nodes) null}}
                type="button"
              >
                Okay
              </button>
            </div>
          </div>
        </div>
      {{/if}}
      <div class="columns">
        <div class="column is-narrow is-400">
          {{#if this.showPollingNotice}}
            <div class="notification is-warning">
              <div class="columns">
                <div class="column">
                  <h3 class="title is-4">
                    No Live Updating
                  </h3>
                  <p>
                    The topology visualization depends on too much data to continuously poll.
                  </p>
                </div>
                <div class="column is-centered is-minimum">
                  <button
                    data-test-polling-notice-dismiss
                    class="button is-warning"
                    type="button"
                    onclick={{toggle-action "showPollingNotice" this}}
                  >
                    Okay
                  </button>
                </div>
              </div>
            </div>
          {{/if}}
          <div class="boxed-section">
            <div class="boxed-section-head">
              Legend
              {{#if (cannot "list all jobs")}}
                <span
                  aria-label="Your ACL token may limit your ability to list all allocations"
                  class="tag is-warning pull-right tooltip multiline"
                >
                  Partial View
                </span>
              {{/if}}
            </div>
            <div class="boxed-section-body">
              <div class="legend">
                <h3 class="legend-label">
                  Metrics
                </h3>
                <dl class="legend-terms">
                  <dt>
                    M:
                  </dt>
                  <dd>
                    Memory
                  </dd>
                  <dt>
                    C:
                  </dt>
                  <dd>
                    CPU
                  </dd>
                </dl>
              </div>
              <div class="legend">
                <h3 class="legend-label">
                  Allocation Status
                </h3>
                <dl class="legend-terms">
                  <div class="legend-term">
                    <dt>
                      <span class="color-swatch is-wide running" title="Running"></span>
                    </dt>
                    <dd>
                      Running
                    </dd>
                  </div>
                  <div class="legend-term">
                    <dt>
                      <span class="color-swatch is-wide pending" title="Starting"></span>
                    </dt>
                    <dd>
                      Starting
                    </dd>
                  </div>
                </dl>
              </div>
            </div>
          </div>
          <div class="boxed-section">
            <div data-test-info-panel-title class="boxed-section-head">
              {{#if this.activeNode}}
                Client
              {{else if this.activeAllocation}}
                Allocation
              {{else}}
                Cluster
              {{/if}}
              Details
            </div>
            <div data-test-info-panel class="boxed-section-body">
              {{#if this.activeNode}}
                {{#let this.activeNode.node as |node|}}
                  <div class="dashboard-metric">
                    <p data-test-allocations class="metric">
                      {{this.activeNode.allocations.length}}
                      <span class="metric-label">
                        Allocations
                      </span>
                    </p>
                  </div>
                  <div class="dashboard-metric">
                    <h3 class="pair">
                      <strong>
                        Client:
                      </strong>
                      <LinkTo data-test-client-link @route="clients.client" @model={{node}}>
                        {{node.shortId}}
                      </LinkTo>
                    </h3>
                    <p data-test-name class="minor-pair">
                      <strong>
                        Name:
                      </strong>
                      {{node.name}}
                    </p>
                    <p data-test-address class="minor-pair">
                      <strong>
                        Address:
                      </strong>
                      {{node.httpAddr}}
                    </p>
                    <p data-test-status class="minor-pair">
                      <strong>
                        Status:
                      </strong>
                      {{node.status}}
                    </p>
                  </div>
                  <div class="dashboard-metric">
                    <h3 class="pair">
                      <strong>
                        Draining?
                      </strong>
                      <span data-test-draining class="{{if node.isDraining "status-text is-info"}}">
                        {{if node.isDraining "Yes" "No"}}
                      </span>
                    </h3>
                    <h3 class="pair">
                      <strong>
                        Eligible?
                      </strong>
                      <span
                        data-test-eligible
                        class="{{unless node.isEligible "status-text is-warning"}}"
                      >
                        {{if node.isEligible "Yes" "No"}}
                      </span>
                    </h3>
                  </div>
                  <div class="dashboard-metric with-divider">
                    <p class="metric">
                      {{this.nodeUtilization.totalMemoryFormatted}}
                      <span class="metric-units">
                        {{this.nodeUtilization.totalMemoryUnits}}
                      </span>
                      <span class="metric-label">
                        of memory
                      </span>
                    </p>
                    <div class="columns graphic">
                      <div class="column">
                        <div class="inline-chart">
                          <progress
                            data-test-memory-progress-bar
                            class="progress is-danger is-small"
                            value="{{this.nodeUtilization.reservedMemoryPercent}}"
                            max="1"
                          >
                            {{this.nodeUtilization.reservedMemoryPercent}}
                          </progress>
                        </div>
                      </div>
                      <div class="column is-minimum">
                        <span class="nowrap" data-test-percentage>
                          {{format-percentage this.nodeUtilization.reservedMemoryPercent total=1}}
                        </span>
                      </div>
                    </div>
                    <div class="annotation" data-test-memory-absolute-value>
                      <strong>
                        {{format-scheduled-bytes this.nodeUtilization.totalReservedMemory}}
                      </strong>
                      /
                      {{format-scheduled-bytes this.nodeUtilization.totalMemory}}
                      reserved
                    </div>
                  </div>
                  <div class="dashboard-metric">
                    <p class="metric">
                      {{this.nodeUtilization.totalCPU}}
                      <span class="metric-units">
                        MHz
                      </span>
                      <span class="metric-label">
                        of CPU
                      </span>
                    </p>
                    <div class="columns graphic">
                      <div class="column">
                        <div class="inline-chart" data-test-percentage-bar>
                          <progress
                            data-test-cpu-progress-bar
                            class="progress is-info is-small"
                            value="{{this.nodeUtilization.reservedCPUPercent}}"
                            max="1"
                          >
                            {{this.nodeUtilization.reservedCPUPercent}}
                          </progress>
                        </div>
                      </div>
                      <div class="column is-minimum">
                        <span class="nowrap" data-test-percentage>
                          {{format-percentage this.nodeUtilization.reservedCPUPercent total=1}}
                        </span>
                      </div>
                    </div>
                    <div class="annotation" data-test-cpu-absolute-value>
                      <strong>
                        {{format-scheduled-hertz this.nodeUtilization.totalReservedCPU}}
                      </strong>
                      /
                      {{format-scheduled-hertz this.nodeUtilization.totalCPU}}
                      reserved
                    </div>
                  </div>
                {{/let}}
              {{else if this.activeAllocation}}
                <div class="dashboard-metric">
                  <h3 class="pair">
                    <strong>
                      Allocation:
                    </strong>
                    <LinkTo
                      data-test-id
                      @route="allocations.allocation"
                      @model={{this.activeAllocation}}
                      class="is-primary"
                    >
                      {{this.activeAllocation.shortId}}
                    </LinkTo>
                  </h3>
                  <p data-test-sibling-allocs class="minor-pair">
                    <strong>
                      Sibling Allocations:
                    </strong>
                    {{this.siblingAllocations.length}}
                  </p>
                  <p data-test-unique-placements class="minor-pair">
                    <strong>
                      Unique Client Placements:
                    </strong>
                    {{this.uniqueActiveAllocationNodes.length}}
                  </p>
                </div>
                <div class="dashboard-metric with-divider">
                  <h3 class="pair">
                    <strong>
                      Job:
                    </strong>
                    <LinkTo
                      data-test-job
                      @route="jobs.job"
                      @model={{this.activeAllocation.job}}
                    >
                      {{this.activeAllocation.job.name}}
                    </LinkTo>
                    <span class="is-faded" data-test-task-group>
                      /
                      {{this.activeAllocation.taskGroupName}}
                    </span>
                  </h3>
                  <p class="minor-pair">
                    <strong>
                      Type:
                    </strong>
                    {{this.activeAllocation.job.type}}
                  </p>
                  <p class="minor-pair">
                    <strong>
                      Priority:
                    </strong>
                    {{this.activeAllocation.job.priority}}
                  </p>
                </div>
                <div class="dashboard-metric with-divider">
                  <h3 class="pair">
                    <strong>
                      Client:
                    </strong>
                    <LinkTo
                      data-test-client
                      @route="clients.client"
                      @model={{this.activeAllocation.node}}
                    >
                      {{this.activeAllocation.node.shortId}}
                    </LinkTo>
                  </h3>
                  <p class="minor-pair">
                    <strong>
                      Name:
                    </strong>
                    {{this.activeAllocation.node.name}}
                  </p>
                  <p class="minor-pair">
                    <strong>
                      Address:
                    </strong>
                    {{this.activeAllocation.node.httpAddr}}
                  </p>
                </div>
                <div class="dashboard-metric with-divider">
                  <PrimaryMetric::Allocation
                    @allocation={{this.activeAllocation}}
                    @metric="memory"
                    class="is-short"
                  />
                </div>
                <div class="dashboard-metric">
                  <PrimaryMetric::Allocation
                    @allocation={{this.activeAllocation}}
                    @metric="cpu"
                    class="is-short"
                  />
                </div>
              {{else}}
                <div class="columns is-flush">
                  <div class="dashboard-metric column">
                    <p data-test-node-count class="metric justify">
                      {{this.model.nodes.length}}
                      <span class="metric-label">
                        Clients
                      </span>
                    </p>
                  </div>
                  <div class="dashboard-metric column">
                    <p data-test-alloc-count class="metric justify">
                      {{this.scheduledAllocations.length}}
                      <span class="metric-label">
                        Allocations
                      </span>
                    </p>
                  </div>
                  <div class="dashboard-metric column">
                    <p data-test-node-pool-count class="metric justify">
                      {{this.model.nodePools.length}}
                      <span class="metric-label">
                        Node Pools
                      </span>
                    </p>
                  </div>
                </div>
                <div class="dashboard-metric with-divider">
                  <p class="metric">
                    {{this.totalMemoryFormatted}}
                    <span class="metric-units">
                      {{this.totalMemoryUnits}}
                    </span>
                    <span class="metric-label">
                      of memory
                    </span>
                  </p>
                  <div class="columns graphic">
                    <div class="column">
                      <div class="inline-chart" data-test-percentage-bar>
                        <progress
                          data-test-memory-progress-bar
                          class="progress is-danger is-small"
                          value="{{this.reservedMemoryPercent}}"
                          max="1"
                        >
                          {{this.reservedMemoryPercent}}
                        </progress>
                      </div>
                    </div>
                    <div class="column is-minimum">
                      <span class="nowrap" data-test-memory-percentage>
                        {{format-percentage this.reservedMemoryPercent total=1}}
                      </span>
                    </div>
                  </div>
                  <div class="annotation" data-test-memory-absolute-value>
                    <strong>
                      {{format-bytes this.totalReservedMemory}}
                    </strong>
                    /
                    {{format-bytes this.totalMemory}}
                    reserved
                  </div>
                </div>
                <div class="dashboard-metric">
                  <p class="metric">
                    {{this.totalCPUFormatted}}
                    <span class="metric-units">
                      {{this.totalCPUUnits}}
                    </span>
                    <span class="metric-label">
                      of CPU
                    </span>
                  </p>
                  <div class="columns graphic">
                    <div class="column">
                      <div class="inline-chart" data-test-percentage-bar>
                        <progress
                          data-test-cpu-progress-bar
                          class="progress is-info is-small"
                          value="{{this.reservedCPUPercent}}"
                          max="1"
                        >
                          {{this.reservedCPUPercent}}
                        </progress>
                      </div>
                    </div>
                    <div class="column is-minimum">
                      <span class="nowrap" data-test-cpu-percentage>
                        {{format-percentage this.reservedCPUPercent total=1}}
                      </span>
                    </div>
                  </div>
                  <div class="annotation" data-test-cpu-absolute-value>
                    <strong>
                      {{format-hertz this.totalReservedCPU}}
                    </strong>
                    /
                    {{format-hertz this.totalCPU}}
                    reserved
                  </div>
                </div>
              {{/if}}
            </div>
          </div>
        </div>
        <div class="column">
          <div class="toolbar">
            <div class="toolbar-item">
              {{#if this.model.nodes.length}}
                <SearchBox
                  @inputClass="node-search"
                  @searchTerm={{mut this.searchTerm}}
                  @placeholder="Search clients..."
                />
              {{/if}}
            </div>
            <div class="toolbar-item is-right-aligned is-mobile-full-width">
              <div class="button-bar">
                <MultiSelectDropdown
                  data-test-node-pool-facet
                  @label="Node Pool"
                  @options={{this.optionsNodePool}}
                  @selection={{this.selectionNodePool}}
                  @onSelect={{action this.setFacetQueryParam "qpNodePool"}}
                />
                <MultiSelectDropdown
                  data-test-datacenter-facet
                  @label="Datacenter"
                  @options={{this.optionsDatacenter}}
                  @selection={{this.selectionDatacenter}}
                  @onSelect={{action this.setFacetQueryParam "qpDatacenter"}}
                />
                <MultiSelectDropdown
                  data-test-class-facet
                  @label="Class"
                  @options={{this.optionsClass}}
                  @selection={{this.selectionClass}}
                  @onSelect={{action this.setFacetQueryParam "qpClass"}}
                />
                <MultiSelectDropdown
                  data-test-state-facet
                  @label="State"
                  @options={{this.optionsState}}
                  @selection={{this.selectionState}}
                  @onSelect={{action this.setFacetQueryParam "qpState"}}
                />
                <MultiSelectDropdown
                  data-test-version-facet
                  @label="Version"
                  @options={{this.optionsVersion}}
                  @selection={{this.selectionVersion}}
                  @onSelect={{action this.setFacetQueryParam "qpVersion"}}
                />
              </div>
            </div>
          </div>
          <TopoViz
            @nodes={{this.filteredNodes}}
            @allocations={{this.model.allocations}}
            @onAllocationSelect={{action this.setAllocation}}
            @onNodeSelect={{action this.setNode}}
            @onDataError={{action this.handleTopoVizDataError}}
            @filters={{hash
              search=this.searchTerm
              clientState=this.selectionState
              clientVersion=this.selectionVersion
            }}
          />
        </div>
      </div>
    {{/if}}
  </section>
</PageLayout>